#ifndef LIBPROVIDER_H
#define LIBPROVIDER_H

#include <hld/hld_dev.h>
#include <api/libfs2/stdio.h>
#include <api/libdb/db_return_value.h>
#include <api/libdb/db_config.h>
#include <api/libdb/db_node_combo.h>
#include <api/libdb/db_interface.h>
#include <api/libsat2ip/sat2ip.h>
#include <hld/dsc/dsc.h>


#define MAX_PID_NUM   48
#define PRV_INVALID_CRYPTO_KEY_POS			0xff
#define PRV_INVALID_CRYPTO_STREAM_ID		0xff
#define PRV_INVALID_CRYPTO_STREAM_HANDLE	0xffffffff
#define PRV_INVALID_CRYPTO_MODE				0xffffffff



typedef enum
{
    MEDIA_PROVIDER_STREAM_INFO_STATE_DEAD = 0,
    MEDIA_PROVIDER_STREAM_INFO_STATE_GOON,
    MEDIA_PROVIDER_STREAM_INFO_STATE_OK,
}STREAM_STATE_TYPE;


typedef enum
{    
    REQUEST_STREAM_START = 0,    
    REQUEST_STREAM_UPDATE,
    REQUEST_STREAM_STOP, 
    REQUEST_STREAM_DATA_READ,

    
    REQUEST_CHECK_STREAM_STATUS,//check 1 stream rec,2 stream exception, caller UINT32 
    REQUEST_CHECK_PARAMETER_VALID,//check sat,tp valid.           caller supply sat2ip_stream_info    
    REQUEST_CHECK_GET_PROGRAM_STREAM_FILE_PATH,//check program record stream file path. caller supply array  
    REQUEST_CHECK_GET_PID_STREAM_FILE_PATH,//check record stream file path. caller supply array  
    REQUEST_SERVER_DB_INFOR,// ali private sat2ip client request
    REQUEST_SERVER_DB_ABORT,// abort db infor send.
    REQUEST_CHECK_PROVIDER_STATUS,
}REQ_STREAM_CMD;


#define VIDEO_MAX_PID   4

#ifdef MAX_CA_AUDIO_CNT
#define AUDIO_MAX_PID   MAX_CA_AUDIO_CNT
#else
#define AUDIO_MAX_PID   16
#endif

#define OTHER_MAX_PID   16

typedef enum
{
    PVR2IP_DIR_UPDATE_ADD = 0,
    PVR2IP_DIR_UPDATE_DELETE,
    PVR2IP_DIR_UPDATE_RENAME,
    PVR2IP_DIR_UPDATE_UNDEF,
}PVR2IP_DIR_UPDATE_TYPE;

typedef struct
{
    INT32 vid_num;
    INT32 aud_num;
    INT32 ttx_num;
    INT32 subt_num;
    UINT16 vid_pids[VIDEO_MAX_PID];
    UINT16 aud_pids[AUDIO_MAX_PID];
    UINT16 ttx_pids[OTHER_MAX_PID];
    UINT16 subt_pids[OTHER_MAX_PID];
    UINT16 pmt_pid;
    UINT16 prog_number;
    UINT8  ca_mode;
}CA_CRYPT_INFO;

typedef struct 
{
    CA_CRYPT_INFO   ca_info;
    UINT32          crypt_stream_id;
	UINT32	        crypto_stream_hnd;	    // crypto stream handle used by provider
	UINT32	        crypto_key_pos;		    // crypto stream key pos used by provider 
	DEEN_CONFIG     pvr_reencrypt_config;
    INT32           state;                  //0: un-initialize,1:initiallize free,2:used.
}PRO_ENCRYPT_INFO;


struct sat2ip_stream_info
{
    STREAM_RECORD_TYPE  record_type;        //request fill
    struct sat2ip_sat   sat_src;            //request fill
    struct sat2ip_tp    tp;                 //request fill
    INT32               pid_num;            //request fill
    UINT16              pids[MAX_PID_NUM];  //request fill    
    BOOL                is_scramble;        //request fill
//------------------------------------
    UINT32              pvr_rec_handle;
    UINT32              ts_route_id;
    INT32               stream_id_inter;    //response fill 
    INT32               state;              //0:free(dead),1:on going...,2:OK,response fill
    UINT8               ret_file_dir[1024]; //response fill
    UINT32              para_valid;
    struct dmx_device   *dmx_dev;
    PRO_ENCRYPT_INFO    *crypt_info;
    BOOL                failure;            //response fill
    INT32               type;               //request type, reponse 
    RETURN_REQUEST      ret_err_code;       //response error code;
    void                *debug_info;
    void                *ringbuf;
    void                *priv;              //reserve
    INT32               socket_fd;          //request fill
};

typedef struct _pvr2ip_record_info
{
    UINT32	record_size;
    UINT32  duration;
    UINT32	ts_bitrate; 
}pvr2ip_record_info;


typedef struct sat2ip_stream_info  S2IP_M_INFO;
typedef struct sat2ip_stream_info* PS2IP_M_INFO;


typedef int (*PIPE_RW) (INT32 id,unsigned char * buffer_in,unsigned int siz);
typedef void (*AP_CALLBACK)(UINT32 event_type,UINT32 para1,UINT32 para2,BOOL sync);

typedef UINT32 (*REQ_BUFFER)(UINT32 req_size,UINT32 *addr);
typedef  void  (*FREE_BUFFER)(UINT32 addr);
    


INT32  media_provider_io_cmd(INT32 stream_id,REQ_STREAM_CMD cmd,UINT32 param,UINT32 affix_param);
INT32 media_provider_rpid_read_ring_buffer(INT32 stream_id,UINT8 *buffer,INT32 size);
INT32 media_provider_get_fe_count(void);
INT32 media_provider_get_fe_snr(INT32 stream_id,UINT32 *quality);
INT32 media_provider_get_fe_lock(INT32 stream_id,UINT8 *lock);
INT32 media_provider_get_fe_agc(INT32 stream_id,UINT32 *quality);
UINT32 media_provider_get_stream_bitrate(UINT32 stream_id);
struct sat2ip_stream_info* media_provider_get_info_by_id(INT32 stream_id);

#if 1
typedef UINT32 PVR2IP_HANDLE;

#define PVR2IP_INVALID_HANDLE 0xFFFFFFFF

/* media_provider_pvr_init
 * Initialize PVR Provider module. Client can try to get pvr list and play after initialize.
 * Application layer call this API when system startup, or UI setting enable PVR2IP feature.
 * return: TRUE when init success; FALSE when failure.
 */
BOOL media_provider_pvr_init(void);

/* media_provider_pvr_clean_up
 * Disable PVR Provider module, after call this API, client can not download pvr list any more.
 * return TRUE when clean up success; FALSE when clean up failure.
 */
BOOL media_provider_pvr_clean_up(void);

/* media_provider_pvr_is_enable
 * Check is PVR provider module is enable or not.
 * return: TRUE module enable; FALSE module disable.
 */
BOOL media_provider_pvr_is_enable(void);

/* media_provider_pvr_add_dir
 * Add PVR direcotry that going to be shared. After add path, only ALI PVR record item can be shared,
 * other media file won't be share to client.
 * @dir_path full path of the directory going to share. e.g. /mnt/uda1/ALIDVRS2
 * return: RET_SUCCESS when success; RET_FAILURE when failure.
 */
RET_CODE media_provider_pvr_add_dir(const char *dir_path);

/* media_provider_pvr_del_dir
 * Delete shared PVR directory.
 * @dir_path full path of the PVR directory. e.g. /mnt/uda1/ALIDVRS2
 * return: RET_SUCCESS when success; RET_FAILURE when directory not exist in list or other reason.
 */
RET_CODE media_provider_pvr_del_dir(const char *dir_path);

/* media_provider_pvr_update_dir
 * Notify pvr provider to update shared pvr direcotry information. 
 * When STB finish new record or delete record item, should call this API to update the list.
 * @dir_path full path of the PVR directory. e.g. /mnt/uda1/ALIDVRS2
 * @type ADD, DEL, REM
 * return: RET_SUCCESS when update success; RET_FAILURE when failure.
 */
RET_CODE media_provider_pvr_update_dir(const char *dir_path, PVR2IP_DIR_UPDATE_TYPE type);

/* media_provider_pvr_add_rec
 *
 * Add one record item to share list.
 *
 * @rec_path Full path of the record item.
 *
 * return RET_SUCCESS if success; RET_FAILTURE if failture.
 */
RET_CODE media_provider_pvr_add_rec(const char *rec_path);

/* media_provider_pvr_del_rec
 *
 * Delete one record item from share list.
 *
 * @rec_path Full path of the record item.
 *
 * return RET_SUCCESS if success; RET_FAILTURE if failture.
 */
RET_CODE media_provider_pvr_del_rec(const char *rec_path);

/* media_provider_pvr_dir_is_streaming
 * This API use to check is there any record item in the specified directory streaming.
 * @dir_path full path of the PVR directory. e.g. /mnt/uda1/ALIDVRS2
 * return: TRUE there are some record item is streaming; FALSE no recording is streaming.
 */
BOOL media_provider_pvr_dir_is_streaming(const char *dir_path);

/* media_provider_pvr_rec_is_streaming
 * This API use to check is the specified record item is streaming to client.
 * @rec_path full path of the record item(record item's directory path).
 * return: TRUE the record item is streaming to client; FALSE the record item is not streaming.
 */
BOOL media_provider_pvr_rec_is_streaming(const char *rec_path);

/* media_provider_pvr_get_dir_count
 * Get current how many PVR directory shared.
 * return: The number of direcotry sharing.
 */
UINT32 media_provider_pvr_get_dir_count(void);

/* media_provider_pvr_get_dir_name
 * This API use to get directory name that in share list by index.
 * @index The index in share list, from 0 to count that get from API media_provider_pvr_get_dir_count.
 * @dir_path The buffer to get direcotry path name.
 * @dir_path_len The buffer length.
 * return: RET_SUCCESS get directory success; RET_FAILURE get directory failure.
 */
RET_CODE media_provider_pvr_get_dir_name(UINT32 index, char *dir_path, UINT32 dir_path_len);

/* media_provider_pvr_get_list
 * This API use to get and send out PVR list, call by HTTP server.
 * @id The send out fifo id pass from HTTP server.
 * @send_out_cb The function the send data out, pass from HTTP server.
 * return: RET_SUCCESS get pvr list success; RET_FAILURE get pvr list failure.
 */
RET_CODE media_provider_pvr_get_list(INT32 id, PIPE_RW send_out_cb);

/* media_provider_pvr_record_open
 * This API use open record item that going to streaming, call by server. server can read 
 * data after open success.
 * @record_uid Every record item will be allocate one unique id when client get pvr list.
 * return: Valid handle when open success; Invalid handle value when open failure.
 */
PVR2IP_HANDLE media_provider_pvr_record_open(UINT32 record_uid);

/* media_provider_pvr_record_close
 * Close record item that streaming. server can not read data after close.
 * @handle The return handle when call media_provider_pvr_record_open
 * return TRUE close success; FALSE close failure.
 */
BOOL media_provider_pvr_record_close(PVR2IP_HANDLE handle);

/* media_provider_pvr_record_read
 * Read record item data. Call by server.
 * @handle The return handle when call media_provider_pvr_record_open
 * @buf The buffer use to fill reading data.
 * @size The buffer size.
 * return: Data size read success.
 */
UINT32 media_provider_pvr_record_read(PVR2IP_HANDLE handle,UINT8 *buf,UINT32 size);

/* media_provider_pvr_time_seek
 * Seek to the specified time.
 * @handle The return handle when call media_provider_pvr_record_open
 * @second The time going to seek to.
 * return TRUE seek success; FALSE seek failure.
 */
BOOL media_provider_pvr_time_seek(PVR2IP_HANDLE handle, UINT32 second);

/* media_provider_pvr_get_rec_info
 * Get specified record item's information from pvr provider.
 * @uid The unique id of record item.
 * @info Output.
 * return: TRUE when get success; FALSE when get failure.
 */
BOOL media_provider_pvr_get_rec_info(UINT32 uid, pvr2ip_record_info *info);

/* media_provider_pvr_get_user_key
 * Get private key.
 * @buf Output key buffer.
 * @buf_len buffer length.
 * return TRUE get success; FALSE get key failure.
 */
BOOL media_provider_pvr_get_user_key(UINT8 *buf, UINT32 buf_len);

/* media_provider_pvr_get_stream_bitrate
 *
 * Get specified PVR record item's bitrate.
 *
 * @uid PVR2IP record item's unique ID.
 * 
 * return Bitrate.
 */
UINT32 media_provider_pvr_get_stream_bitrate(UINT32 uid);

/* media_provider_pvr_has_share_item
 * 
 * Check is there any sharing items.
 *
 * return TRUE if have some items; FALSE no share item.
 */
BOOL media_provider_pvr_has_share_item(void);
#endif

/* media_provider_register_buffer_function
 * 
 * configurate malloc and free buffer function.
 *
 * return void
 */

void media_provider_register_buffer_function(REQ_BUFFER req_fun,FREE_BUFFER free_fun);

#endif



